/*******************************************************************************************************/
/*******************************************************************************************************/
//   //                                                                         //
//   // $Workfile:: calibrate_load_sensing.c             $Revision:: 1                                                                               //
//   // $JustDate:
//   //                                                                         //
//   //      Dingli Scissors ECU                                                               //
//   //      Load Sensing algorithm                                                      //
//   //                                                                         //
/*******************************************************************************************************/
/*******************************************************************************************************/
//   //                                                                         //
//   //    Procedure:                                                              //
//   //                                                                         //
//   //                                                                         //
//   // DESCRIPTION: This procedure creates an array of pressures vs corresponding                //
//   //           angles to be used for load sensing during normal operation.                  //
//   //                                                                         //
//   //                                                                         //
//   // uc_Calibration_Status Codes:                                                  //
//   //                                                                         //
//   //       0xC0        All calibration is successful.  No errors.                        //
//   //       0x80 (Bit 7)   Fully-loaded platform calibration is successful.  No errors.         //
//   //       0x40 (Bit 6)   Unloaded platform calibration is successful.  No errors.          //
//   //       0x20 (Bit 5)   An error has occurred.  Check other bits for the specific error.     //
//   //       0x10 (Bit 4)   Calibration failed due to being out of tolerance.                 //
//   //       0x08 (Bit 3)   The angle sensor measurement is too low.                       //
//   //       0x04 (Bit 2)   The angle sensor measurement is too high.                      //
//   //       0x02 (Bit 1)   The pressure sensor measurement is too low.                       //
//   //       0x01 (Bit 0)   The pressure sensor measurement is too high.                   //
//   //                                                                         //
//   //                                                                         //
//   //       0x00        The system is out of calibration or has never bee calibrated.        //
//   //       0x2F        Calibration failed due to too many calibration points.  This will    //
//   //                   automatically restart the calibration procedure with changes to         //
//   //                   correct the problem.  This error should not be permanent, unless there  //
//   //                   is another problem which forces the lift to continually sample too      //
// //                     many points.                                             //
//   //       0xE0        Calibration check is in a warning state.  The system is              //
// //                     approaching out of tolerance.  Recalibration is recommended.         //
//   //       0xF0        Calibration is out of tolerance.  Repairs                      //
// //                     or recalibration are required before further use.                 //
// //                     Shut down lift functions.                                   //
//   //       0xFF        The system is out of calibration or has never bee calibrated.        //
//   //                                                                         //
//   //                                                                         //
/*******************************************************************************************************/
/*******************************************************************************************************/
//
#include "load_sensing.h"                                                     //
#include "main.h"                                                          //
#include "common.h"                                                           //
#include "calibrate_load_sensing.h"                                              //
#include "eeprom.h"                                                           //
#include "fet.h"                                                           //
#include "display.h"                                                       //
#include "control.h"
#include "nvm.h"
#include "alarm.h"
#include "serial.h"

#define MOTOR_ON_DELAY   LIFT_Data.bMotorEnableDelay * CONTROL_CYCLE
#define CHASSIS_UP_PWM   lift_setup.lift_up_curve.bPwmPosAdjust
//
/*******************************************************************************************************/
/*******************************************************************************************************/
//
void calibrate_load_sense(unsigned int  ui_Calibrated_Scissor_Angle_Array[]               // Output: The array of stored scissor angles
                          , unsigned int  ui_Calibrated_Cylinder_Pressure_Array[]           // Output: The cooresponding array of stored cylinder pressures
                          , unsigned int  ui_NoLoad_Angle_Sensor_Array[]                 // Output: The array of stored scissor angles
                          , unsigned int  ui_NoLoad_Pressure_Sensor_Array[]              // Output: The cooresponding array of stored cylinder pressures
                          , unsigned int  ui_Up_Calibrated_Scissor_Angle_Array[]            // Output: The array of stored scissor angles
                          , unsigned int  ui_Up_Calibrated_Cylinder_Pressure_Array[]           // Output: The cooresponding array of stored cylinder pressures
                          , unsigned int  ui_Up_NoLoad_Angle_Sensor_Array[]                 // Output: The array of stored scissor angles
                          , unsigned int  ui_Up_NoLoad_Pressure_Sensor_Array[]              // Output: The cooresponding array of stored cylinder pressures
                          , unsigned int  ui_Dn_Calibrated_Scissor_Angle_Array[]            // Output: The array of stored scissor angles
                          , unsigned int  ui_Dn_Calibrated_Cylinder_Pressure_Array[]           // Output: The cooresponding array of stored cylinder pressures
                          , unsigned int  ui_Dn_NoLoad_Angle_Sensor_Array[]                 // Output: The array of stored scissor angles
                          , unsigned int  ui_Dn_NoLoad_Pressure_Sensor_Array[]              // Output: The cooresponding array of stored cylinder pressures
                          , unsigned char uc_Load_Sensing_Array_Size                  // Input: The number of elements in each stored array
                          , unsigned char *uc_Calibration_Status                      // Output: The calibration status and errors
                          //                      ,unsigned int  *ui_Max_Cylinder_Angle
                         )



{
   unsigned int   ui_Delay_Increment;
   unsigned int   ui_Measured_Cylinder_Pressure;
   unsigned int   ui_Measured_Scissor_Angle;
   unsigned int   ui_Storage_Variable;
   unsigned int   ui_Temp1;
   unsigned int   ui_Temp2;
   unsigned int   ui_Stablize_Time;
   unsigned char  uc_Array_Position;
   unsigned char  uc_Start_Calibration;
   unsigned char  uc_Sensor_Type;
   unsigned char  uc_Temp;
   unsigned int   *ui_array_Temp1;
   unsigned int   *ui_array_Temp2;

   uc_Start_Calibration = calibration_procedure_start_sequence();
   if(uc_Start_Calibration & 0x03)
   {
      Fets.word = STOP_PLATFORM_MOVEMENT;
      LIFT_Data.calc_pwm1 = 0;            //IO.PDR8.BIT.B2 = 0;
      LIFT_Pwm();
      ui_Delay_Increment = 0;
      //                MAIN_Data.dwElevationTime = 0;
      ui_Stablize_Time = STABILIZATION_DELAY / BACKGROUND_LOOP_TIME;

      // Delay 200ms to make sure platform message is sent to the platform to turn off the buzzer.
      for(uc_Temp = 0; uc_Temp < 20; uc_Temp++)
      {
         ALARM_Data.fPlatform = 0;   // Turn off the platform's buzzer.
         serial();
         delay_mSec(10);
      }

recalibrate:
      blow_horn();                                                         //
      ui_Measured_Scissor_Angle = read_angle_sensor();                           // Record the new Angle Sensor reading.
      ui_Measured_Cylinder_Pressure = read_cylinder_pressure();                    //

      if((uc_Start_Calibration == 1) || (uc_Start_Calibration == 2) || (uc_Start_Calibration == 5) || (uc_Start_Calibration == 6))
      {
         if (!((MAIN_Data.fAnglePolarity && (ui_Measured_Scissor_Angle > (NVM_TripAngleState.anData[UP_LIMIT_ANGLE] - UP_LIMIT_OFFSET))) ||
              (!MAIN_Data.fAnglePolarity && (ui_Measured_Scissor_Angle < (NVM_TripAngleState.anData[UP_LIMIT_ANGLE] + UP_LIMIT_OFFSET))))
            )
         {
            Fets.word = RAISE_PLATFORM;                                          // Continue raising the platform.
            if(ELEC3 == lift_setup.bLiftType)
            {
                  delay_mSec(50);
               Fets.word = RAISE_PLATFORM2;
            }                                      // Continue raising the platform.
            delay_mSec(MOTOR_ON_DELAY);
            LIFT_Data.calc_pwm1 = 100; //IO.PDR8.BIT.B2 = 1;
         }
         else
         {
            LIFT_Data.calc_pwm1 = 0; //IO.PDR8.BIT.B2 = 0;
            delay_mSec(50);
            Fets.word = STOP_PLATFORM_MOVEMENT;
         }                                   // Continue raising the platform.
   //    if (CHASSIS_UP_LIMIT_REACHED) LIFT_Data.calc_pwm1 = 0; //IO.PDR8.BIT.B2 = 0;                             // Turn on the motor controller to full speed
   //    else LIFT_Data.calc_pwm1 = 100; //IO.PDR8.BIT.B2 = 1;
         LIFT_Pwm();
         if(ELEC3 == lift_setup.bLiftType)
         {
            ui_Temp2 = RAISE_PLATFORM_TIME_ELEC;
         }
         else
         {
            ui_Temp2 = RAISE_PLATFORM_TIME;
         }
         for(ui_Storage_Variable = 0;                                          // Raise the platform for the next measurement.
             ui_Storage_Variable < (ui_Temp2/*RAISE_PLATFORM_TIME*/ / BACKGROUND_LOOP_TIME);         //
               ui_Storage_Variable += 1)                                         //
         {
            delay_mSec(BACKGROUND_LOOP_TIME);                                       // A delay is required because the background loop is no longer running.
            ui_Measured_Scissor_Angle = read_angle_sensor();                           // Record the new Angle Sensor reading.
            ui_Measured_Cylinder_Pressure = read_cylinder_pressure();                     //

         }                                                                 //
      }

      if(!(uc_Start_Calibration & 0x04))
      {
         LIFT_Data.calc_pwm1 = 0; //IO.PDR8.BIT.B2 = 0;
         LIFT_Pwm();
         delay_mSec(50);
         Fets.word = STOP_PLATFORM_MOVEMENT;                                        // Stop raising the platform.
         for(ui_Storage_Variable = 0;                                          // Delay and filter a series of measurements.
             ui_Storage_Variable < ui_Stablize_Time;            //
             ui_Storage_Variable++)                                            //
        {
            delay_mSec(BACKGROUND_LOOP_TIME);                                       // A delay is required because the background loop is no longer running.
            if(uc_Start_Calibration == 1)                                           // High pressure calibration
            {
                ui_Calibrated_Scissor_Angle_Array[0] = read_angle_sensor();                // Record the new Loaded platform Angle Sensor reading.
                ui_Calibrated_Cylinder_Pressure_Array[0] = read_cylinder_pressure();       //
                ui_Temp1 = ui_Calibrated_Scissor_Angle_Array[0];                        //
                ui_Temp2 = ui_Calibrated_Cylinder_Pressure_Array[0];                    //
            }                                                              //
            else if(uc_Start_Calibration == 2)                                                           //
            {
                ui_NoLoad_Angle_Sensor_Array[0] = read_angle_sensor();                     // Record the new Unloaded platform Angle Sensor reading.
                ui_NoLoad_Pressure_Sensor_Array[0] = read_cylinder_pressure();             //
                ui_Temp1 = ui_NoLoad_Angle_Sensor_Array[0];                             //
                ui_Temp2 = ui_NoLoad_Pressure_Sensor_Array[0];                          //
            }                                                              //
            else if(uc_Start_Calibration == 9)                                           // High pressure calibration
            {
               ui_Dn_Calibrated_Scissor_Angle_Array[0] = read_angle_sensor();                // Record the new Loaded platform Angle Sensor reading.
               ui_Dn_Calibrated_Cylinder_Pressure_Array[0] = read_cylinder_pressure();       //
               ui_Temp1 = ui_Dn_Calibrated_Scissor_Angle_Array[0];                        //
               ui_Temp2 = ui_Dn_Calibrated_Cylinder_Pressure_Array[0];                    //

            }                                                              //
            else if(uc_Start_Calibration == 10)                                                        //
            {
               ui_Dn_NoLoad_Angle_Sensor_Array[0] = read_angle_sensor();                     // Record the new Unloaded platform Angle Sensor reading.
               ui_Dn_NoLoad_Pressure_Sensor_Array[0] = read_cylinder_pressure();             //
               ui_Temp1 = ui_Dn_NoLoad_Angle_Sensor_Array[0];                             //
               ui_Temp2 = ui_Dn_NoLoad_Pressure_Sensor_Array[0];                          //
            }
         }
      }
      if(uc_Start_Calibration == 5)                                           // High pressure calibration
      {
          ui_Up_Calibrated_Scissor_Angle_Array[0] = read_angle_sensor();                // Record the new Loaded platform Angle Sensor reading.
          ui_Up_Calibrated_Cylinder_Pressure_Array[0] = read_cylinder_pressure();       //
         ui_Temp1 = ui_Up_Calibrated_Scissor_Angle_Array[0];                        //
         ui_Temp2 = ui_Up_Calibrated_Cylinder_Pressure_Array[0];                    //
      }                                                              //
      else if(uc_Start_Calibration == 6)                                                        //
      {
          ui_Up_NoLoad_Angle_Sensor_Array[0] = read_angle_sensor();                     // Record the new Unloaded platform Angle Sensor reading.
          ui_Up_NoLoad_Pressure_Sensor_Array[0] = read_cylinder_pressure();             //
         ui_Temp1 = ui_Up_NoLoad_Angle_Sensor_Array[0];                             //
         ui_Temp2 = ui_Up_NoLoad_Pressure_Sensor_Array[0];                          //
      }                                                              //
      uc_Temp = check_for_sensor_errors(ui_Temp1, ui_Temp2);                           //
      if(uc_Temp)                                                          //
      {
         if(uc_Start_Calibration & 0x02)
         {
            *uc_Calibration_Status &= 0xBF;                                         // Record the calibration data fault
         }
         else
         {
            *uc_Calibration_Status &= 0x7F;
         }
         *uc_Calibration_Status |= uc_Temp;                                      // Record the calibration data fault
         record_write(RECORD_LOAD_SENSING_CALIBRATION_STATUS                         // Calibration was successful.
                    , 0x01                                                   //
                    , uc_Calibration_Status);                                   //
         lower_the_platform(&ui_NoLoad_Angle_Sensor_Array[0]                            //
                          , 0x01);                                        //
         goto end_calibration;                                                //
      }                                                                 //
      ui_Temp1 = 0;                                                        //
      ui_Temp2 = 0;                                                        //
      read_angle_sensor();
      read_cylinder_pressure();
      for(uc_Array_Position = 1;                                               //
          uc_Array_Position < uc_Load_Sensing_Array_Size;                         //
          uc_Array_Position++)                                           //
      {
         if(((uc_Start_Calibration == 1) || (uc_Start_Calibration == 2) || (uc_Start_Calibration == 5) || (uc_Start_Calibration == 6)) &&
            (!((MAIN_Data.fAnglePolarity && (ui_Measured_Scissor_Angle > (NVM_TripAngleState.anData[UP_LIMIT_ANGLE] - UP_LIMIT_OFFSET))) ||
              (!MAIN_Data.fAnglePolarity && (ui_Measured_Scissor_Angle < (NVM_TripAngleState.anData[UP_LIMIT_ANGLE] + UP_LIMIT_OFFSET)))))
            )
         {
            Fets.word = RAISE_PLATFORM;                                          // Continue raising the platform.
            if(ELEC3 == lift_setup.bLiftType)
            {
               if((uc_Start_Calibration == 1) || (uc_Start_Calibration == 2))
               {
                  delay_mSec(50);
               }
               Fets.word = RAISE_PLATFORM2;
            }                                      // Continue raising the platform.
            delay_mSec(MOTOR_ON_DELAY);
            LIFT_Data.calc_pwm1 = 100; //IO.PDR8.BIT.B2 = 1;
         }
         else if(((uc_Start_Calibration == 9) || (uc_Start_Calibration == 10)) &&
                 (!((MAIN_Data.fAnglePolarity && (ui_Measured_Scissor_Angle < (NVM_TripAngleState.anData[DOWN_LIMIT_ANGLE] + DOWN_LIMIT_OFFSET))) ||
                    (!MAIN_Data.fAnglePolarity && (ui_Measured_Scissor_Angle > (NVM_TripAngleState.anData[DOWN_LIMIT_ANGLE] - DOWN_LIMIT_OFFSET)))))
                )
         {
            Fets.word = LOWER_PLATFORM;
            LIFT_Data.calc_pwm1 = 0;
         }
         else
         {
            Fets.word = STOP_PLATFORM_MOVEMENT;
            LIFT_Data.calc_pwm1 = 0;
         }                                   // Continue raising the platform.

         LIFT_Pwm();

         if(ELEC3 == lift_setup.bLiftType)
         {
            ui_Temp2 = RAISE_PLATFORM_TIME_ELEC;
         }
         else
         {
            ui_Temp2 = RAISE_PLATFORM_TIME;
         }
         for(ui_Storage_Variable = 0;                                       // Raise the platform for the next measurement.
             ui_Storage_Variable < ((ui_Temp2 /*RAISE_PLATFORM_TIME*/ +                       //
             ui_Delay_Increment) / BACKGROUND_LOOP_TIME);             //
             ui_Storage_Variable++)                                         //
         {
            //
            //if(((uc_Start_Calibration == 1) || (uc_Start_Calibration == 2) || (uc_Start_Calibration == 5) || (uc_Start_Calibration == 6)) &&
            //   (uc_Array_Position < 5)
            //  )
            //{
            //   ui_Storage_Variable ++;
            //}                       //

            delay_mSec(BACKGROUND_LOOP_TIME);                                    // A delay is required because the background loop is no longer running.

            if(((uc_Start_Calibration == 1) || (uc_Start_Calibration == 2) || (uc_Start_Calibration == 5) || (uc_Start_Calibration == 6)) &&
                (((MAIN_Data.fAnglePolarity && (ui_Measured_Scissor_Angle > (NVM_TripAngleState.anData[UP_LIMIT_ANGLE] - UP_LIMIT_OFFSET))) ||
                 (!MAIN_Data.fAnglePolarity && (ui_Measured_Scissor_Angle < (NVM_TripAngleState.anData[UP_LIMIT_ANGLE] + UP_LIMIT_OFFSET)))))
               )
            {
               LIFT_Data.calc_pwm1 = 0; //IO.PDR8.BIT.B2 = 0;                             // Turn on the motor controller to full speed
               LIFT_Pwm();
               delay_mSec(50);
               Fets.word = STOP_PLATFORM_MOVEMENT;                               // Continue raising the platform.
               if (ELEC3 == lift_setup.bLiftType)
               {
                  ui_Temp2 = RAISE_PLATFORM_TIME_ELEC;
               }
               else
               {
                  ui_Temp2 = RAISE_PLATFORM_TIME;
               }
               ui_Storage_Variable = ((ui_Temp2/*RAISE_PLATFORM_TIME*/ +                        //
                              ui_Delay_Increment)/BACKGROUND_LOOP_TIME);
            }
            else if(((uc_Start_Calibration == 9) || (uc_Start_Calibration == 10)) &&
                    (((MAIN_Data.fAnglePolarity && (ui_Measured_Scissor_Angle < (NVM_TripAngleState.anData[DOWN_LIMIT_ANGLE] + DOWN_LIMIT_OFFSET))) ||
                      (!MAIN_Data.fAnglePolarity && (ui_Measured_Scissor_Angle > (NVM_TripAngleState.anData[DOWN_LIMIT_ANGLE] - DOWN_LIMIT_OFFSET)))))
                   )
            {
               Fets.word = STOP_PLATFORM_MOVEMENT;                               // Continue raising the platform.
               LIFT_Data.calc_pwm1 = 0; //IO.PDR8.BIT.B2 = 0;                             // Turn on the motor controller to full speed
               LIFT_Pwm();
               if(ELEC3 == lift_setup.bLiftType)
               {
                  ui_Temp2 = RAISE_PLATFORM_TIME_ELEC;
               }
               else
               {
                  ui_Temp2 = RAISE_PLATFORM_TIME;
               }

               ui_Storage_Variable = ((ui_Temp2/*RAISE_PLATFORM_TIME*/ +                        //
                                       ui_Delay_Increment) / BACKGROUND_LOOP_TIME);
            }
            ui_Measured_Scissor_Angle = read_angle_sensor();                        // Record the new Angle Sensor reading.
            ui_Measured_Cylinder_Pressure = read_cylinder_pressure();                  //
         }                                                              //
         if(!(uc_Start_Calibration & 0x04))
         {
            LIFT_Data.calc_pwm1 = 0; //IO.PDR8.BIT.B2 = 0;                             // Turn on the motor controller to full speed
            LIFT_Pwm();
            delay_mSec(50);
            Fets.word = STOP_PLATFORM_MOVEMENT;                                     // Continue raising the platform.
            for(ui_Storage_Variable = 0;                                       // Raise the platform for the next measurement.
                ui_Storage_Variable < ui_Stablize_Time;         //
                ui_Storage_Variable++)                                         //
            {                                                                      // Look for consecutive increases.
                delay_mSec(BACKGROUND_LOOP_TIME);                                    // A delay is required because the background loop is no longer running.
                ui_Measured_Scissor_Angle = read_angle_sensor();                        // Record the new Angle Sensor reading.
                ui_Measured_Cylinder_Pressure = read_cylinder_pressure();                 //
            }
         }                                                              //
         uc_Temp = check_for_sensor_errors(ui_Measured_Scissor_Angle                    //
                                         , ui_Measured_Cylinder_Pressure);            //
         if (uc_Temp == 0x21) ui_Temp1++;                                     // The pressure sensor can fault to over-pressure during calibration, but there must be two consecutive faults.
         if((uc_Temp && (uc_Temp != 0x21))                                     // Any fault other than over-pressure is always a fault.
          || ui_Temp1 == 0x06                                               // Three consecutive over-pressure faults is a fault.  There may be two consecutive over-pressure readings at the end of calibration.
          || (ui_Temp1 && (!uc_Temp)))                                       // If one overpressure fault occurs, then the next measurement must also be an overpressure reading.
         {
            if(uc_Start_Calibration & 0x02)
            {
                *uc_Calibration_Status &= 0xBF;                                         // Record the calibration data fault
            }
            else
            {
               *uc_Calibration_Status &= 0x7F;
            }
            *uc_Calibration_Status |= uc_Temp;                                   //
            record_write(RECORD_LOAD_SENSING_CALIBRATION_STATUS                      // Record the calibration data fault.
                       , 0x01                                                //
                       , uc_Calibration_Status);                                //
            lower_the_platform(&ui_Calibrated_Scissor_Angle_Array[0]                    //
                             , uc_Array_Position);                              //
            goto end_calibration;                                             //
         }                                                              //
         if(uc_Start_Calibration == 1)                                           // High pressure calibration.  (Fully loaded platform).
         {
            ui_array_Temp1 = &ui_Calibrated_Scissor_Angle_Array[0];
            ui_array_Temp2 = &ui_Calibrated_Cylinder_Pressure_Array[0];
         }                                                              // End if (uc_Start_Calibration == 1)
         else if(uc_Start_Calibration == 2)                                                           // Empty platform calibration.  (uc_Start_Calibration == 2)
         {                                                              // Low pressure calibration
            ui_array_Temp1 = &ui_NoLoad_Angle_Sensor_Array[0];
            ui_array_Temp2 = &ui_NoLoad_Pressure_Sensor_Array[0];
         }                                                              // End else
         else if(uc_Start_Calibration == 5)                                         // High pressure calibration.  (Fully loaded platform).
         {
            ui_array_Temp1 = &ui_Up_Calibrated_Scissor_Angle_Array[0];
            ui_array_Temp2 = &ui_Up_Calibrated_Cylinder_Pressure_Array[0];
         }                                                              // End if (uc_Start_Calibration == 1)
         else if(uc_Start_Calibration == 6)                                                           // Empty platform calibration.  (uc_Start_Calibration == 2)
         {                                                              // Low pressure calibration
            ui_array_Temp1 = &ui_Up_NoLoad_Angle_Sensor_Array[0];
            ui_array_Temp2 = &ui_Up_NoLoad_Pressure_Sensor_Array[0];
         }                                                                 // End for (   uc_Array_Position = 1;
         else if(uc_Start_Calibration == 9)                                         // High pressure calibration.  (Fully loaded platform).
         {
            ui_array_Temp1 = &ui_Dn_Calibrated_Scissor_Angle_Array[0];
            ui_array_Temp2 = &ui_Dn_Calibrated_Cylinder_Pressure_Array[0];
         }                                                              // End if (uc_Start_Calibration == 1)
         else if(uc_Start_Calibration == 10)                                                           // Empty platform calibration.  (uc_Start_Calibration == 2)
            // Low pressure calibration
         {
            ui_array_Temp1 = &ui_Dn_NoLoad_Angle_Sensor_Array[0];
            ui_array_Temp2 = &ui_Dn_NoLoad_Pressure_Sensor_Array[0];
         }                                                                 // End for (   uc_Array_Position = 1;

         uc_Sensor_Type = 0x00;                                            // The angle A/D decreases with increasing platform height.
         if(ui_Measured_Scissor_Angle >  *ui_array_Temp1)         //
            uc_Sensor_Type = 1;                                            // The angle A/D increases with increasing platform height.
         *(ui_array_Temp1 + uc_Array_Position) =                     //
                                            ui_Measured_Scissor_Angle;             // Record the load sensing array values.
         if((uc_Array_Position < 2) || (ui_Measured_Cylinder_Pressure <
                                     (*(ui_array_Temp2 + uc_Array_Position - 1) + PRES_DIFF_THRESHOLD)))
            *(ui_array_Temp2 + uc_Array_Position) =               //
                                    ui_Measured_Cylinder_Pressure;            //
         else
            *(ui_array_Temp2 + uc_Array_Position) =               //
                                    *(ui_array_Temp2 + uc_Array_Position - 1);      //

         if((uc_Array_Position >= 5) &&
            ((uc_Sensor_Type &&                                             // The calibration angle has not changed.
               (*(ui_array_Temp1 + uc_Array_Position)                              // The platform must be at its highest position.
                    <= *(ui_array_Temp1 + uc_Array_Position - 1))) ||     // End the calibration procedure.
            (!uc_Sensor_Type &&                                                          //
               (*(ui_array_Temp1 + uc_Array_Position)                              //
                    >= *(ui_array_Temp1 + uc_Array_Position - 1))))          //
           )//
         {
            if((uc_Start_Calibration == 9) || (uc_Start_Calibration == 10))
            {
               uc_Temp = uc_Array_Position-1;                                    //
               while (uc_Temp > (uc_Array_Position-1 - uc_Temp))
               {
                  ui_Temp1 = *(ui_array_Temp1 + uc_Temp);
                  *(ui_array_Temp1 + uc_Temp) =                //
                     *(ui_array_Temp1 + uc_Array_Position-1-uc_Temp);      //
                  *(ui_array_Temp1 + uc_Array_Position-1-uc_Temp) =                 //
                     ui_Temp1;      //
                  ui_Temp1 = *(ui_array_Temp2 + uc_Temp);
                  *(ui_array_Temp2 + uc_Temp) =                //
                     *(ui_array_Temp2 + uc_Array_Position-1-uc_Temp);      //
                  *(ui_array_Temp2 + uc_Array_Position-1-uc_Temp) =                 //
                     ui_Temp1;      //
                  uc_Temp--;
               }
            }

            uc_Temp = uc_Array_Position;                                   //
            *(ui_array_Temp1 + uc_Array_Position) =                  //
                     *(ui_array_Temp1 + uc_Array_Position - 1);   //
            *(ui_array_Temp2 + uc_Array_Position) =               //
                     *(ui_array_Temp2 + uc_Array_Position - 1); //
            uc_Array_Position++;                                        //
            while(uc_Array_Position < uc_Load_Sensing_Array_Size)                   // Fill the array with the last value.
            {                                                        //
                *(ui_array_Temp1 + uc_Array_Position) =               //
                               *(ui_array_Temp1 + uc_Temp);           // ui_Measured_Scissor_Angle;
                *(ui_array_Temp2 + uc_Array_Position) =            //
                               *(ui_array_Temp2 + uc_Temp);        // ui_Measured_Cylinder_Pressure;
                uc_Array_Position++;                                     //
            }                                                        //
            if(uc_Start_Calibration == 1)                                           // High pressure calibration.  (Fully loaded platform).
            {                                                              //
               record_write(RECORD_LOAD_SENSING_PRESSURE_SENSOR_ARRAY                   // Store the results before lowering the platform.
                          , uc_Load_Sensing_Array_Size * 2                      //
                          , (UINT8 *)&ui_Calibrated_Cylinder_Pressure_Array[0]);               //
               delay_mSec(50);                                                // This is to reset the watchdog timer.
               record_write(RECORD_LOAD_SENSING_ANGLE_SENSOR_ARRAY                   // Store the results before lowering the platform.
                          , uc_Load_Sensing_Array_Size * 2                      //
                          , (UINT8 *)&ui_Calibrated_Scissor_Angle_Array[0]);                //
               delay_mSec(50);                                                // This is to reset the watchdog timer.
     //        *uc_Calibration_Status &= 0xC0;                                   //
     //        *uc_Calibration_Status |= 0x80;                                   //
     //        record_write( RECORD_LOAD_SENSING_CALIBRATION_STATUS                 // Calibration was successful.
     //                 , 0x01                                             //
     //                 , uc_Calibration_Status);                             //
               uc_Start_Calibration = 9;
               goto recalibrate;                                        //
            }
            else if(uc_Start_Calibration == 2)
            {
               record_write(RECORD_NOLOAD_PRESSURE_SENSOR_ARRAY                      // Store the results before lowering the platform.
                          , uc_Load_Sensing_Array_Size * 2                      //
                          , (UINT8 *)&ui_NoLoad_Pressure_Sensor_Array[0]);                     //
               delay_mSec(50);                                                // This is to reset the watchdog timer.
               record_write(RECORD_NOLOAD_ANGLE_SENSOR_ARRAY                         // Store the results before lowering the platform.
                          , uc_Load_Sensing_Array_Size * 2                      //
                          , (UINT8 *)&ui_NoLoad_Angle_Sensor_Array[0]);                     //
               delay_mSec(50);                                                // This is to reset the watchdog timer.
     //        *uc_Calibration_Status &= 0xC0;                                   //
     //        *uc_Calibration_Status |= 0x40;                                   //
     //        record_write( RECORD_LOAD_SENSING_CALIBRATION_STATUS                 // Calibration was successful
     //                 , 0x01                                             //
     //                 , uc_Calibration_Status);                             //
               uc_Start_Calibration = 10;
               goto recalibrate;                                        //
            }
            if(uc_Start_Calibration == 9)                                           // High pressure calibration.  (Fully loaded platform).
               //
            {
               record_write(RECORD_DN_LOAD_SENSING_PRESSURE_SENSOR_ARRAY                  // Store the results before lowering the platform.
                            , uc_Load_Sensing_Array_Size * 2                      //
                            , (UINT8 *)&ui_Dn_Calibrated_Cylinder_Pressure_Array[0]);               //
               delay_mSec(50);                                                // This is to reset the watchdog timer.
               record_write(RECORD_DN_LOAD_SENSING_ANGLE_SENSOR_ARRAY                  // Store the results before lowering the platform.
                            , uc_Load_Sensing_Array_Size * 2                      //
                            , (UINT8 *)&ui_Dn_Calibrated_Scissor_Angle_Array[0]);                //
               delay_mSec(50);                                                // This is to reset the watchdog timer.
               //             *uc_Calibration_Status &= 0xC0;                                   //
               //             *uc_Calibration_Status |= 0x80;                                   //
               //             record_write( RECORD_LOAD_SENSING_CALIBRATION_STATUS                 // Calibration was successful.
               //                      , 0x01                                             //
               //                      , uc_Calibration_Status);                             //
               Fets.word = LOWER_PLATFORM;
               delay_mSec(6000);
               Fets.word = STOP_PLATFORM_MOVEMENT;
               uc_Start_Calibration = 5;
               goto recalibrate;                                        //
            }
            else if(uc_Start_Calibration == 10)
            {
               record_write(RECORD_DN_NOLOAD_PRESSURE_SENSOR_ARRAY                     // Store the results before lowering the platform.
                            , uc_Load_Sensing_Array_Size * 2                      //
                            , (UINT8 *)&ui_Dn_NoLoad_Pressure_Sensor_Array[0]);                     //
               delay_mSec(50);                                                // This is to reset the watchdog timer.
               record_write(RECORD_DN_NOLOAD_ANGLE_SENSOR_ARRAY                        // Store the results before lowering the platform.
                            , uc_Load_Sensing_Array_Size * 2                      //
                            , (UINT8 *)&ui_Dn_NoLoad_Angle_Sensor_Array[0]);                     //
               delay_mSec(50);                                                // This is to reset the watchdog timer.
               //                *uc_Calibration_Status &= 0xC0;                                   //
               //                *uc_Calibration_Status |= 0x40;                                   //
               //                record_write( RECORD_LOAD_SENSING_CALIBRATION_STATUS                 // Calibration was successful
               //                         , 0x01                                             //
               //                         , uc_Calibration_Status);                             //
               Fets.word = LOWER_PLATFORM;
               delay_mSec(6000);
               Fets.word = STOP_PLATFORM_MOVEMENT;
               uc_Start_Calibration = 6;
               goto recalibrate;                                        //
            }
            else if(uc_Start_Calibration == 5)
            {
                record_write(RECORD_UP_LOAD_SENSING_PRESSURE_SENSOR_ARRAY                   // Store the results before lowering the platform.
                         , uc_Load_Sensing_Array_Size * 2                      //
                         , (UINT8 *)&ui_Up_Calibrated_Cylinder_Pressure_Array[0]);               //
                delay_mSec(50);                                                // This is to reset the watchdog timer.
                record_write(RECORD_UP_LOAD_SENSING_ANGLE_SENSOR_ARRAY                   // Store the results before lowering the platform.
                         , uc_Load_Sensing_Array_Size * 2                      //
                         , (UINT8 *)&ui_Up_Calibrated_Scissor_Angle_Array[0]);                //
                delay_mSec(50);                                                // This is to reset the watchdog timer.
                *uc_Calibration_Status &= 0xC0;                                   //
                *uc_Calibration_Status |= 0x80;                                   //
                record_write(RECORD_LOAD_SENSING_CALIBRATION_STATUS                   // Calibration was successful.
                         , 0x01                                             //
                         , uc_Calibration_Status);                             //
                lower_the_platform(&ui_Calibrated_Scissor_Angle_Array[0]                 //
                               , 0x00);                                  //
            }
            else if(uc_Start_Calibration == 6)
            {
                record_write(RECORD_UP_NOLOAD_PRESSURE_SENSOR_ARRAY                      // Store the results before lowering the platform.
                         , uc_Load_Sensing_Array_Size * 2                      //
                         , (UINT8 *)&ui_Up_NoLoad_Pressure_Sensor_Array[0]);                     //
                delay_mSec(50);                                                // This is to reset the watchdog timer.
                record_write(RECORD_UP_NOLOAD_ANGLE_SENSOR_ARRAY                         // Store the results before lowering the platform.
                      , uc_Load_Sensing_Array_Size * 2                      //
                         , (UINT8 *)&ui_Up_NoLoad_Angle_Sensor_Array[0]);                     //
                delay_mSec(50);                                                // This is to reset the watchdog timer.
                *uc_Calibration_Status &= 0xC0;                                   //
                *uc_Calibration_Status |= 0x40;                                   //
                record_write(RECORD_LOAD_SENSING_CALIBRATION_STATUS                   // Calibration was successful
                         , 0x01                                             //
                         , uc_Calibration_Status);                             //
                lower_the_platform(&ui_NoLoad_Angle_Sensor_Array[0]                      //
                               , 0x00);                                  // Lower the platform and end the calibration procedure.
            }
         }                                                           // End if ((uc_Sensor_Type &&
         else                                                        //
         {
            if(uc_Array_Position == (uc_Load_Sensing_Array_Size - 1))               //
            {
                ui_Delay_Increment += 1000;                                    // There were too many measurements.  Increase the "up platform" time and re-calibrate.
                *uc_Calibration_Status |= 0x2F;                                //
                record_write(RECORD_LOAD_SENSING_CALIBRATION_STATUS                // Calibration failed due to too many calibration points.
                         , 0x01                                          //
                         , uc_Calibration_Status);                          //
                lower_the_platform(ui_array_Temp1                //
                               , 0x00);                               //
                goto recalibrate;                                        //
            }                                                        //
         }                                                              // End if (uc_Start_Calibration == 1)
      }                                                                 // End for (   uc_Array_Position = 1;

end_calibration:                                                                 // A sensor fault was detected.
      LIFT_Data.calc_pwm1 = 0; //IO.PDR8.BIT.B2 = 0;                             // Turn on the motor controller to full speed
      LIFT_Pwm();
      Fets.word = END_PLATFORM_CALIBRATION;                                      //
   }                                                                    // End if (uc_Start_Calibration & 0x03)
}                                                                       // End void calibrate_load_sense(    unsigned int  ui_Calibrated_Scisso
                                                                                //
/**********END**********END**********END**********END**********END**********END**********END************/


/*******************************************************************************************************/
/*******************************************************************************************************/
//   //                                                                         //
//   // PROCEDURE:  unsigned char check_for_sensor_errors (   unsigned int ui_Angle_Sensor           //
//   //                                        unsigned int ui_Pressure_Sensor)       //
//   //                                                                         //
//   // DESCRIPTION: This procedure checks the sensor measurements for overvoltage and undervoltage     //
//   //             faults.                                                        //
//   //                                                                         //
//   //                                                                         //
//   // uc_Errors Codes:                                                           //
//   //       0x80 (Bit 7)   Reserved.  Do not use.                                      //
//   //       0x40 (Bit 6)   Reserved.  Do not use.                                      //
//   //       0x20 (Bit 5)   An error has occurred.  Check other bits for the specific error.     //
//   //       0x10 (Bit 4)   Reserved.  Do not use.                                      //
//   //       0x08 (Bit 3)   The angle sensor measurement is too low.                       //
//   //       0x04 (Bit 2)   The angle sensor measurement is too high.                      //
//   //       0x02 (Bit 1)   The pressure sensor measurement is too low.                       //
//   //       0x01 (Bit 0)   The pressure sensor measurement is too high.                   //
//   //       0x00        No sensor errors were detected.                                //
//   //                                                                         //
//   //                                                                         //
/*******************************************************************************************************/
/*******************************************************************************************************/
                                                                                //
unsigned char check_for_sensor_errors(unsigned int ui_Angle_Sensor                      //
                              , unsigned int ui_Pressure_Sensor)                 //
{                                                                       //
           unsigned char uc_Errors;                                                   //
                                                                                //
           uc_Errors = 0x00;                                                       //
   if (ui_Pressure_Sensor < MINIMUM_ALLOWABLE_PRESSURE_SENSOR_VOLTAGE) uc_Errors |= 0x22;    // The pressure sensor reading is less than 0.35 VDC.  This is an under-voltage error.                                                             //
   else if  (ui_Pressure_Sensor > MAXIMUM_ALLOWABLE_PRESSURE_SENSOR_VOLTAGE) uc_Errors |= 0x21; // The pressure sensor reading is greater than 4.65 VDC.  This is an over-voltage error.
   if (ui_Angle_Sensor < MINIMUM_ALLOWABLE_ANGLE_SENSOR_VOLTAGE) uc_Errors |= 0x28;       // The angle sensor reading is less than 0.35 VDC.  This is an under-voltage error.
   else if  (ui_Angle_Sensor > MAXIMUM_ALLOWABLE_ANGLE_SENSOR_VOLTAGE) uc_Errors |= 0x24;    // The angle sensor reading is greater than 4.65 VDC.  This is an over-voltage error.
           return uc_Errors;                                                       //
        }                                                                       //
                                                                                //

unsigned char check_for_sensor_errors2(unsigned int ui_Pressure_Sensor
                                       , unsigned int ui_Pressure_Sensor2)
{
   unsigned char uc_Errors;
   unsigned int Pressure_SUM = 0;

   uc_Errors = 0x00;
   Pressure_SUM = ui_Pressure_Sensor + ui_Pressure_Sensor2;

   if((Pressure_SUM > MAXIMUM_SUM_ALLOWABLE_PRESSURE_SENSOR_VOLTAGE) || (Pressure_SUM < MINIMUM_SUM_ALLOWABLE_PRESSURE_SENSOR_VOLTAGE))
   {
      uc_Errors = 0x40;
   }

   return uc_Errors;
}
/**********END**********END**********END**********END**********END**********END**********END************/





/*******************************************************************************************************/
/*******************************************************************************************************/
//   //                                                                         //
// //   void lower_the_platform ( unsigned int ui_Calibrated_Scissor_Angle_Array[]                // Output: The array of stored scissor angles
// //                     , unsigned char   uc_Platform_Error_Height)                       //
//   //                                                                         //
//   // DESCRIPTION: This procedure lowers the platform onto the cradle after calibration.           //
//   //                                                                         //
/*******************************************************************************************************/
/*******************************************************************************************************/
                                                                                //
void lower_the_platform(unsigned int  ui_Calibrated_Scissor_Angle_Array[]                  // Output: The array of stored scissor angles
                      , unsigned char   uc_Platform_Error_Height)                       //
{
   unsigned char  uc_Sensor_Type;                                                //
   unsigned int   ui_Measured_Scissor_Angle;                                     //
   unsigned int   ui_Storage_Variable;                                        //
   unsigned int   ui_Horn_Counter;                                            //

   blow_horn();                                                            //
//    MAIN_Data.dwElevationTime += CAL_OFFSET;
   ui_Measured_Scissor_Angle = read_cylinder_pressure();                            //  Dummy Read to keep pressure filter up to date
   ui_Measured_Scissor_Angle = read_angle_sensor();                                 //
   uc_Sensor_Type = 0;                                                        //  Decreasing angle measurements with increasing platform height.
   if(ui_Calibrated_Scissor_Angle_Array[2] > ui_Calibrated_Scissor_Angle_Array[0])        //
      uc_Sensor_Type = 1;                                                     //  Increasing angle measurements with increasing platform height.

   ui_Horn_Counter = 0;                                                    //
   Fets.word = LOWER_PLATFORM;                                                   // Lower the platform.
   if(uc_Platform_Error_Height)                                               //
   {
      for(ui_Storage_Variable = 0                                              //
         ; ui_Storage_Variable < 300 * (uc_Platform_Error_Height)                   //
         ; ui_Storage_Variable++)                                             // Lower the platform for 3 seconds per measurement.
      {                                                                 // Record the new Angle Sensor reading.
         ui_Measured_Scissor_Angle = read_cylinder_pressure();                      //  Dummy Read to keep pressure filter up to date
         ui_Measured_Scissor_Angle = read_angle_sensor();                           // Record the new Angle Sensor reading.
         delay_mSec(BACKGROUND_LOOP_TIME);                                       // A delay is required because the background loop is no longer running.

         if (++ui_Horn_Counter > 1000/BACKGROUND_LOOP_TIME) ui_Horn_Counter = 0;          //
         else if (ui_Horn_Counter > 500/BACKGROUND_LOOP_TIME) Fets.word = LOWER_PLATFORM; //
         else Fets.word = LOWER_PLATFORM_W_HORN;                                    //
      }                                                                 //
   }                                                                    //
   else if(uc_Sensor_Type)                                                    //
   {
      while(ui_Measured_Scissor_Angle > ui_Calibrated_Scissor_Angle_Array[1])             //
      {                                                                 // Return the platform to the ground position.
          ui_Measured_Scissor_Angle = read_cylinder_pressure();                        //  Dummy Read to keep pressure filter up to date
         ui_Measured_Scissor_Angle = read_angle_sensor();                           // Record the new Angle Sensor reading.
         delay_mSec(BACKGROUND_LOOP_TIME);                                       // A delay is required because the background loop is no longer running.

         if (++ui_Horn_Counter > 1000/BACKGROUND_LOOP_TIME) ui_Horn_Counter = 0;          //
         else if (ui_Horn_Counter > 500/BACKGROUND_LOOP_TIME) Fets.word = LOWER_PLATFORM; //
         else Fets.word = LOWER_PLATFORM_W_HORN;                                    //
      }                                                                 //
   }                                                                    //
   else                                                                 //
   {
      while(ui_Measured_Scissor_Angle < ui_Calibrated_Scissor_Angle_Array[1])             //
      {                                                                 // Return the platform to the ground position.           //
          ui_Measured_Scissor_Angle = read_cylinder_pressure();                        //  Dummy Read to keep pressure filter up to date
         ui_Measured_Scissor_Angle = read_angle_sensor();                           // Record the new Angle Sensor reading.
         delay_mSec(BACKGROUND_LOOP_TIME);                                       // A delay is required because the background loop is no longer running.

         if (++ui_Horn_Counter > 1000/BACKGROUND_LOOP_TIME) ui_Horn_Counter = 0;          //
         else if (ui_Horn_Counter > 500/BACKGROUND_LOOP_TIME) Fets.word = LOWER_PLATFORM; //
         else Fets.word = LOWER_PLATFORM_W_HORN;                                    //
      }                                                                 //
   }                                                                    //
   for(ui_Storage_Variable = 0; ui_Storage_Variable < CAL_DOWN_LOOPS; ui_Storage_Variable++)             // Lower the platform for 5 more seconds.  Then Start over.
   {                                                                    // Record the new Angle Sensor reading.
      ui_Measured_Scissor_Angle = read_cylinder_pressure();                         //  Dummy Read to keep pressure filter up to date
      ui_Measured_Scissor_Angle = read_angle_sensor();                              // Record the new Angle Sensor reading.
      delay_mSec(BACKGROUND_LOOP_TIME);                                          // A delay is required because the background loop is no longer running.

      if (++ui_Horn_Counter > 1000/BACKGROUND_LOOP_TIME) ui_Horn_Counter = 0;             //
      else if (ui_Horn_Counter > 500/BACKGROUND_LOOP_TIME) Fets.word = LOWER_PLATFORM;    //
      else Fets.word = LOWER_PLATFORM_W_HORN;                                       //
   }                                                                    //
   Fets.word = STOP_PLATFORM_MOVEMENT;                                           // Continue raising the platform.
   LIFT_Data.calc_pwm1 = 0; //IO.PDR8.BIT.B2 = 0;                             // Turn on the motor controller to full speed
   LIFT_Pwm();
}                                                                       //
                                                                                //
/**********END**********END**********END**********END**********END**********END**********END************/





/*******************************************************************************************************/
/*******************************************************************************************************/
//   //                                                                         //
//   // PROCEDURE:  unsigned char calibration_procedure_start_sequence(void)                   //
//   //                                                                         //
//   // DESCRIPTION: This procedure steps through a sequence required to activate                 //
//   //       the calibration routine.  Remember that this routine is entered                     //
//   //       every backgroung loop, which is 10 mSec                                       //
//   //                                                                         //
/*******************************************************************************************************/
/*******************************************************************************************************/
//
unsigned char calibration_procedure_start_sequence(void)                            //
{   //
   static unsigned char suc_Sequence_Tracker;                                       //
   unsigned char uc_Switch_Status;                                               //
   unsigned char uc_OK_to_Start_Calibration;                                     //
   //
   uc_OK_to_Start_Calibration = 0;                                               //
   uc_Switch_Status = check_calibration_switches();                                 //
   //
   if(uc_Switch_Status & (ACTIVATED_SWITCH_TIME_OUT | DEACTIVATED_SWITCH_TIME_OUT))          // Check for lack of activation or status change.
   {      // A time out has occurred. Start over.
      suc_Sequence_Tracker = 0;                                               //
   }                                                                    //
   else                                                                 //
   {      //
      if(uc_Switch_Status == DOWN_SWITCH)
      {
         switch(suc_Sequence_Tracker)
         {
            default:                                                       //
               suc_Sequence_Tracker = 0;                                         //
            case  0:                                                    // Down 1.
            case  1:                                                    // Down 2.
            case  2:                                                    // Down 3.
            case  3:                                                    // Down 4.
            case  4:                                                    // Down 5.
            case  6:                                                    // Down 1.
            case  7:                                                    // Down 2.
            case  8:                                                    // Down 3.
            case  9:                                                    // Down 4.
            case  10:                                                      // Down 5.
            case  12:                                                      // Down 1.
            case  13:                                                      // Down 2.
            case  14:                                                      // Down 3.
            case  15:                                                      // Down 4.
            case  17:                                                      // Down 1.
            case  18:                                                      // Down 2.
               suc_Sequence_Tracker++;
               break;
            case  16:                                                      // Down 5.
               uc_OK_to_Start_Calibration = 1;                                   // The "fully-loaded platform calibration" sequence has been completed.
               suc_Sequence_Tracker = 0;                                      // 5 Downs, 1 Up, 5 Downs, 1 Up, 5 Downs
               break;                                                      //
            case  19:                                                      // Down 3.
               uc_OK_to_Start_Calibration = 2;                                   // The "empty platform calibration" sequence has been completed.
               suc_Sequence_Tracker = 0;                                      // 5 Downs, 1 Up, 5 Downs, 1 Up, 1 Down, 1 Up, 3Downs
               break;                                                      //
         }
      }
      else if(uc_Switch_Status == UP_SWITCH)
      {
         switch(suc_Sequence_Tracker)
         {
            default:                                                       //
               suc_Sequence_Tracker = 0;                                         //
               break;
            case  5:                                                    // Up 1.
            case  11:                                                      // Up 1.
            case  20:                                                      // Up 3.
            case  21:                                                      // Up 4.
            case  22:                                                      // Up 5.
               suc_Sequence_Tracker++;
               break;
            case  12:                                                      // Up 2.
               suc_Sequence_Tracker = 20;
               break;
            case  13:                                                      // Up 1.
               suc_Sequence_Tracker = 17;
               break;
            case  23:                                                      // Up 6.
//             uc_OK_to_Start_Calibration = 4;                                   // The "test calibration validity" sequence has been completed.
               suc_Sequence_Tracker = 0;                                      // 5 Downs, 1 Up, 5 Downs, 6 Ups
               break;                                                         //
         }
      }
   }                                                                    // End else
   return uc_OK_to_Start_Calibration;                                            //
}                                                                       //  End unsigned char calibration_procedure_start_sequence(void)
//
/********END**********END**********END**********END**********END**********END**********END******/





/*******************************************************************************************************/
/*******************************************************************************************************/
//   //                                                                         //
//   // PROCEDURE:  unsigned char check_calibration_switches(void)                             //
//   //                                                                         //
//   // DESCRIPTION: This procedure steps through a sequence required to activate                 //
//   //       the calibration routines.  It monitors switch positions and returns valid           //
//   //       switch presses.  Remember that this routine is entered                           //
//   //       every backgroung loop, which is 10 mSec                                       //
//   //                                                                         //
/*******************************************************************************************************/
/*******************************************************************************************************/
                                                                                //
unsigned char check_calibration_switches(void)                                      //
{                                                                       //
   static unsigned char suc_Button_Pressed_Loop_Counter;                            //
   static unsigned char suc_Button_Released_Loop_Counter;                              //
   static unsigned char suc_Button_Press_Status;                                    //
   unsigned char uc_Status_Return;                                               //
                                                                        //
   uc_Status_Return = 0;                                                      //
   if(CHASSIS_DOWN_SWITCH_IS_ACTIVATED || CHASSIS_UP_SWITCH_IS_ACTIVATED)                 //
   {                                                                    //
      suc_Button_Released_Loop_Counter = 0;                                      //
      if(++suc_Button_Pressed_Loop_Counter > 250)                                // Activating a switch for 2.50
      {                                                                 // seconds is too long.
         suc_Button_Pressed_Loop_Counter = 250;                                  // Start counting again.
         suc_Button_Press_Status = 0;                                         //
         uc_Status_Return = ACTIVATED_SWITCH_TIME_OUT;                              //
      }                                                                 //
      else if(suc_Button_Pressed_Loop_Counter > 15)                                 // The switch has been pressed for
      {                                                                 // 150 mSec but less than 2.5 seconds
         if (CHASSIS_DOWN_SWITCH_IS_ACTIVATED) suc_Button_Press_Status = DOWN_SWITCH;     //
         else suc_Button_Press_Status = UP_SWITCH;                               //
      }                                                                 //
   }                                                                    //
   else                                                                 // No switch is activated
   {                                                                    //
      suc_Button_Pressed_Loop_Counter = 0;                                       // Reset the loop counters.
      if(++suc_Button_Released_Loop_Counter > 250)                                  // The buttons have been released
      {                                                                 // for too long.
         suc_Button_Released_Loop_Counter = 250;                                    //
         suc_Button_Press_Status = 0;                                         //
         uc_Status_Return = DEACTIVATED_SWITCH_TIME_OUT;                            //
      }                                                                 //
      else if(suc_Button_Released_Loop_Counter > 15)                                // The switch has been released for
      {                                                                 // for 150 mSec.
         if(suc_Button_Press_Status)                                          // The switch was pressed for 150
         {                                                              // mSec, then released for 150 mSec
            uc_Status_Return = suc_Button_Press_Status;                             //
            suc_Button_Press_Status = 0;                                      //
            suc_Button_Released_Loop_Counter = 0;                                //
         }                                                              //
      }                                                                 //
   }                                                                    //
   return uc_Status_Return;                                                   //
}                                                                       //
                                                                                //
/**********END**********END**********END**********END**********END**********END**********END************/





/*******************************************************************************************************/
/*******************************************************************************************************/
//   //                                                                         //
//   // PROCEDURE:  void delay_mSec (unsigned int ui_Delay_in_Milliseconds)                       //
//   //                                                                         //
//   // DESCRIPTION: This procedure delays for the vehicle to stabilize,                       //
//   //       prior to a measurement, or to simulate a background timing loop.                 //
//   //                                                                         //
/*******************************************************************************************************/
/*******************************************************************************************************/
                                                                                //
void delay_mSec(unsigned int ui_Delay_in_Milliseconds)                                 //
{                                                                       //
   unsigned int ui_Timer_Storage;                                                //
                                                                        //
   ui_Timer_Storage = TIMER_Data.wTestClock;                                     // Delay for filtering
   while((TIMER_Data.wTestClock - ui_Timer_Storage) < ui_Delay_in_Milliseconds)           // and other timing.
   {                                                                    //
      FEED_THE_WATCHDOG;                                                      // This is to avoid a WDT reset.
   }                                                                    //
}                                                                       //
                                                                                //
/**********END**********END**********END**********END**********END**********END**********END************/








/*******************************************************************************************************/
/*******************************************************************************************************/
//   //                                                                         //
//   //                                                                         //
//   //  PROCEDURE: void blow_horn (void)                                                //
//   //                                                                         //
//   //  DESCRIPTION: This procedure blows the horn, once a second                             //
//   //             to warn that movement is about to begin.                                //
//   //                                                                         //
/*******************************************************************************************************/
/*******************************************************************************************************/
                                                                                //
void blow_horn(void)                                                          //
{                                                                       //
   unsigned int ui_Storage_Variable;                                             //
                                                                        //
   for(ui_Storage_Variable = 0; ui_Storage_Variable < 5; ui_Storage_Variable++)           // Used to indicate that the platform
   {                                                                    // calibration is about to begin, or
      Fets.word = TEST_HORN;                                                  // the platrorm is about to be lowered.
      delay_mSec(500);                                                     //
      Fets.word = STOP_PLATFORM_MOVEMENT;                                        //
      LIFT_Data.calc_pwm1 = 0; //IO.PDR8.BIT.B2 = 0;                             // Turn on the motor controller to full speed
      LIFT_Pwm();
      delay_mSec(500);                                                     //
   }                                                                    //
}                                                                       //
                                                                                //
/**********END**********END**********END**********END**********END**********END**********END************/
